package com.tfswx.jcyw.dmzc.window;

import cn.hutool.core.comparator.PinyinComparator;
import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.core.util.IdUtil;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.tfswx.jcyw.dmzc.api.ApiUtil;
import com.tfswx.jcyw.dmzc.api.dto.*;
import com.tfswx.jcyw.dmzc.bean.Gbc;
import com.tfswx.jcyw.dmzc.component.MyComboBox;
import com.tfswx.jcyw.dmzc.component.MyTextArea;
import com.tfswx.jcyw.dmzc.config.CommonData;
import com.tfswx.jcyw.dmzc.dto.ZcbzTableItem;
import com.tfswx.jcyw.dmzc.service.DlxxService;
import com.tfswx.jcyw.dmzc.service.XmxxService;
import com.tfswx.jcyw.dmzc.util.MessageUtil;
import com.tfswx.jcyw.dmzc.util.NotificationUtil;
import com.tfswx.jcyw.dmzc.util.PinyinUtil;
import com.tfswx.jcyw.dmzc.util.ProjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ricky
 * @date 2022/10/18
 */
@Slf4j
public class DmzcjlAddWindow extends DialogWrapper {
    private static final DlxxService dlxx = DlxxService.getInstance();
    private final String openFilePath;
    private final int startLine;
    private final int endLine;
    private final Project project;
    private final XmxxService xmxxService;
    private JPanel windowPanel;
    private JLabel zcwjLabel;
    private JLabel tpLabel;
    private JLabel zcxmLabel;
    private JScrollPane zcbzTableScrollPane;
    private JPanel leftPanel;
    private JCheckBox msCheckbox;
    private JTextField psjhbhTextField;
    private JPanel zcOrPsPanel;
    private JPanel zcbzPanel;
    private JButton kfryBtn;
    private JLabel kfryLabel;
    private String kfrybm;
    private byte[] tpBytes;
    private final List<ZcbzTableItem> model = new ArrayList<>();


    public DmzcjlAddWindow(Project project, byte[] tpBytes, String openFilePath, int startLine, int endLine) {
        super(true);
        this.project = project;
        this.tpBytes = tpBytes;
        this.openFilePath = openFilePath;
        this.startLine = startLine;
        this.endLine = endLine;


        Dimension leftPanelDimension = new Dimension();
        leftPanelDimension.setSize(400, -1);
        leftPanel.setPreferredSize(leftPanelDimension);

        xmxxService = XmxxService.getInstance(project).getState();

        zcbzTableScrollPane.setBorder(BorderFactory.createEmptyBorder());
        zcbzTableScrollPane.getVerticalScrollBar().setUnitIncrement(16);

        JViewport viewport = new JViewport();
        JPanel jPanel = new JPanel(null);
        int height = 30;
        JLabel jLabel = new JLabel("序号");
        jLabel.setBounds(0, 0, 30, height);
        jPanel.add(jLabel);
        JLabel jLabel1 = new JLabel("标准名称");
        jLabel1.setBounds(30, 0, 60, height);
        jPanel.add(jLabel1);
        JLabel jLabel2 = new JLabel("评审意见");
        jLabel2.setBounds(320, 0, 60, height);
        jPanel.add(jLabel2);
        JLabel jLabel3 = new JLabel("意见等级");
        jLabel3.setBounds(620, 0, 60, height);
        jPanel.add(jLabel3);
        viewport.setView(jPanel);
        viewport.setPreferredSize(new Dimension(800, height));
        zcbzTableScrollPane.setColumnHeader(viewport);

        setTitle(project.getName() + "-添加走查记录");

        zcxmLabel.setText(project.getName());

        zcbzPanel.setLayout(new GridBagLayout());

        drawImage();
        tpLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
                    // 左键双击图片
//                    new TpViewDialog(DmzcjlAddWindow.this.tpBytes).show();
                    boolean b = new Tp(tpBytes).showAndGet();
                    if (b) {
                        DmzcjlAddWindow.this.tpBytes = CommonData.imageByte;
                        drawImage();
                    }
                }
            }
        });

        msCheckbox.addChangeListener(changeEvent -> {
            JCheckBox checkBox = (JCheckBox) changeEvent.getSource();
            CardLayout layout = (CardLayout) zcOrPsPanel.getLayout();
            if (checkBox.isSelected()) {
                checkBox.setText("评审模式");
                layout.show(zcOrPsPanel, "psCard");
            } else {
                psjhbhTextField.setText(null);
                checkBox.setText("走查模式");
                layout.show(zcOrPsPanel, "zcCard");
            }
        });
        initui();
        init();
    }

    public static void open(Project project, byte[] tpBytes, int startLine, int endLine) {

        String rybm = dlxx.getRybm();
        if (StringUtils.isBlank(rybm)) {
            Notification notification = NotificationUtil.create("未登录！", "代码走查", NotificationType.WARNING);
            notification.addAction(new AnAction("登录") {
                @Override
                public void actionPerformed(@NotNull AnActionEvent e) {
                    DmzcSettingWindow.openSetting(project);
                }
            });
            notification.notify(project);
            return;
        }

        String openFilePath = ProjectUtil.getOpenFilePath(project);

        new DmzcjlAddWindow(project, tpBytes, openFilePath, startLine, endLine).show();
    }

    private void drawImage() {
        // 图片
        ImageIcon tp = new ImageIcon(tpBytes);

        int iconWidth = tp.getIconWidth();
        int iconHeight = tp.getIconHeight();
        Image image = tp.getImage();
        int maxSize = Math.max(iconWidth, iconHeight);
        if (maxSize > 500) {
            int scale = (int) Math.ceil(maxSize / 500.0);
            iconHeight = iconHeight / scale;
            iconWidth = iconWidth / scale;
            image = image.getScaledInstance(iconWidth, iconHeight, Image.SCALE_DEFAULT);
        }
        tp.setImage(image);
        tpLabel.setIcon(tp);
    }

    private void initui() {
        try {
            boolean psms = xmxxService.isPsms();
            if (psms) {
                msCheckbox.setSelected(true);
                String psjhbh = xmxxService.getPsjhbh();
                psjhbhTextField.setText(psjhbh);
            }

            // 走查文件
            zcwjLabel.setText(openFilePath + ":" + startLine + "-" + endLine);

            // 走查人员
            PageParam<RylbQueryParam> rylbQueryParamPageParam = new PageParam<>();
            rylbQueryParamPageParam.setPageNum(1);
            rylbQueryParamPageParam.setPageSize(Integer.MAX_VALUE);
            rylbQueryParamPageParam.setFilter(new RylbQueryParam());
            PageResult<RylbQueryResult> rylbQueryResultPageResult = ApiUtil.fwdApi.queryRylb(rylbQueryParamPageParam);

            // 按名字拼音排序
            PinyinComparator pinyinComparator = new PinyinComparator();
            final List<RylbQueryResult> ryList = rylbQueryResultPageResult.getList().stream().sorted((rylbQueryResult, t1) -> pinyinComparator.compare(rylbQueryResult.getRymc(), t1.getRymc())).collect(Collectors.toList());
            kfrybm = xmxxService.getLastKfrybm();

            for (RylbQueryResult rylbQueryResult : ryList) {
                if (rylbQueryResult.getRybm().equals(kfrybm)) {
                    kfryLabel.setText(rylbQueryResult.getRymc());
                }
                List<String> py = rylbQueryResult.getPy();
                String rymc = rylbQueryResult.getRymc();
                // 全拼
                py.addAll(PinyinUtil.getPinyin(rymc));
                // 首拼
                py.addAll(PinyinUtil.getFirstLetter(rymc));
            }

            kfryBtn.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    new SelectRy(ryList, rylbQueryResult -> EventQueue.invokeLater(() -> {
                        kfrybm = rylbQueryResult.getRybm();
                        kfryLabel.setText(rylbQueryResult.getRymc());
                    })).show();
                }
            });

            // 走查标准分类
            PsbzfllbQueryParam psbzfllbQueryParam = new PsbzfllbQueryParam();
            psbzfllbQueryParam.setPslxbm(dlxx.getPslxbm());
            List<PsbzfllbQueryResult> data = ApiUtil.fwdApi.queryPsbzfllb(psbzfllbQueryParam);

            int i = 1;
            for (PsbzfllbQueryResult datum : data) {
                if ("BFFA39FF65E0408984708C789679818E".equals(datum.getPsbzflbm()) || "前端规范".equals(datum.getPsbzflmc())) {
                    continue;
                }
                if ("844D246A5B4F4D09ABAE3FBB944FAC7E".equals(datum.getPsbzflbm()) || "单元测试".equals(datum.getPsbzflmc())) {
                    continue;
                }
                // 走查标准
                PageParam<PsbzlbQueryParam> psbzlbQueryParamPageParam = new PageParam<>();
                psbzlbQueryParamPageParam.setPageNum(1);
                psbzlbQueryParamPageParam.setPageSize(Integer.MAX_VALUE);
                PsbzlbQueryParam psbzlbQueryParam = new PsbzlbQueryParam();
                psbzlbQueryParam.setPslxbm(dlxx.getPslxbm());
                psbzlbQueryParam.setPsbzflbm(datum.getPsbzflbm());
                psbzlbQueryParamPageParam.setFilter(psbzlbQueryParam);
                PageResult<PsbzlbQueryResult> psbzlbQueryResultPageResult = ApiUtil.fwdApi.queryPsbzlb(psbzlbQueryParamPageParam);
                List<PsbzlbQueryResult> zcbzList = psbzlbQueryResultPageResult.getList();
                if (!zcbzList.isEmpty()) {
                    ZcbzTableItem zcbzTableItem = new ZcbzTableItem();
                    zcbzTableItem.setXh(String.valueOf(i));
                    zcbzTableItem.setPsbzbm("");
                    zcbzTableItem.setBzmc(datum.getPsbzflmc());
                    zcbzTableItem.setZcyj("");
                    zcbzTableItem.setSfktx(false);
                    model.add(zcbzTableItem);
                    int j = 1;
                    for (PsbzlbQueryResult o : zcbzList) {
                        ZcbzTableItem zcbzTableItem1 = new ZcbzTableItem();
                        zcbzTableItem1.setXh(i + "." + j);
                        zcbzTableItem1.setPsbzbm(o.getPsbzbm());
                        zcbzTableItem1.setBzmc(o.getJcnr());
                        zcbzTableItem1.setZcyj("");
                        zcbzTableItem1.setSfktx(true);
                        model.add(zcbzTableItem1);
                        j++;
                    }
                    i++;
                }
            }
            Font font20 = new Font(null, Font.PLAIN, 20);
            List<String> yjdjList = Arrays.asList("1", "2", "3");
            for (int i1 = 0; i1 < model.size(); i1++) {
                ZcbzTableItem zcbzTableItem = model.get(i1);
                if (zcbzTableItem.getSfktx()) {
                    zcbzPanel.add(new JLabel(zcbzTableItem.getXh()), new Gbc(1, i1 + 1));
                    JLabel jLabel = new JLabel("<html>" + zcbzTableItem.getBzmc() + "</html>");
                    jLabel.setPreferredSize(getSize(jLabel, 300));
                    zcbzPanel.add(jLabel, new Gbc(2, i1 + 1));
                    zcbzPanel.add(new MyTextArea(zcbzTableItem, "zcyj"), new Gbc(3, i1 + 1).setInsets(5, 0, 0, 0));
                    zcbzPanel.add(new MyComboBox(zcbzTableItem, "yjdj", yjdjList), new Gbc(4, i1 + 1).setInsets(5, 0, 0, 0));
                } else {
                    JLabel jLabel = new JLabel(zcbzTableItem.getXh());
                    jLabel.setFont(font20);
                    zcbzPanel.add(jLabel, new Gbc(1, i1 + 1, 1, 1));
                    JLabel jLabel1 = new JLabel(zcbzTableItem.getBzmc());
                    jLabel1.setFont(font20);
                    zcbzPanel.add(jLabel1, new Gbc(2, i1 + 1, 1, 1));
                }
            }
        } catch (Exception e) {
            log.error("打开新增窗口失败", e);
            Notification notification = NotificationUtil.create("页面初始化失败！" + e.getMessage(), "代码走查", NotificationType.ERROR);
            notification.notify(project);
            close(CANCEL_EXIT_CODE);
        }
    }

    private Dimension getSize(JLabel jLabel, int width) {
        View v = BasicHTML.createHTMLView(jLabel, jLabel.getText());
        v.setSize(width, Integer.MAX_VALUE);
        int minimumSpan = (int) v.getMinimumSpan(View.Y_AXIS);
        return new Dimension(width, minimumSpan);
    }

    @Override
    protected @Nullable JComponent createCenterPanel() {
        return windowPanel;
    }

    @Override
    protected Action @NotNull [] createActions() {
        Action okAction = new AbstractAction("提交") {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                try {
                    List<ZcbzTableItem> zcyjs = model.stream().filter(item -> StringUtils.isNotBlank(item.getZcyj())).collect(Collectors.toList());
                    if (zcyjs.isEmpty()) {
                        throw new RuntimeException("走查意见不能为空");
                    }

                    if (zcyjs.stream().anyMatch(item -> StringUtils.isBlank(item.getYjdj()))) {
                        throw new RuntimeException("意见等级不能为空");
                    }

                    xmxxService.setLastKfrybm(kfrybm);

                    InputStreamResource jtwj = new InputStreamResource(new ByteArrayInputStream(tpBytes), IdUtil.fastSimpleUUID() + ".png");

                    Map<String, Object> param = new HashMap<>();

                    boolean isPsms = msCheckbox.isSelected();
                    xmxxService.setPsms(isPsms);
                    param.put("gcmc", project.getName());
                    param.put("jtwj", jtwj);
                    param.put("xmlx", xmxxService.getXmlx());
                    param.put("bz", "");
                    param.put("zcywjbh", openFilePath + ":" + startLine + "-" + endLine);

                    for (int i = 0; i < zcyjs.size(); i++) {
                        ZcbzTableItem item = zcyjs.get(i);
                        String zcyj = item.getZcyj();
                        String yjdj = item.getYjdj();
                        String psbzbm = item.getPsbzbm();

                        param.put("zcqks[" + i + "].yjdj", yjdj);
                        param.put("zcqks[" + i + "].zcyj", zcyj);
                        param.put("zcqks[" + i + "].psbzbm", psbzbm);

                        if (!isPsms) {
                            param.put("zcqks[" + i + "].kfrybm", kfrybm);
                            param.put("zcqks[" + i + "].kfrymc", kfryLabel.getText());
                        }
                    }

                    if (isPsms) {
                        // 评审模式
                        String psjhbh = psjhbhTextField.getText();
                        if (StringUtils.isBlank(psjhbh)) {
                            throw new RuntimeException("评审计划编号不能为空");
                        }
                        param.put("psjhbh", psjhbh);
                        xmxxService.setPsjhbh(psjhbh);
                        ApiUtil.fwdApi.addJhdmzc(param);

                        DmpsjlQueryWindow dmpsjlQueryWindow = ServiceManager.getService(project, DmpsjlQueryWindow.class);
                        dmpsjlQueryWindow.queryPsjl();
                    } else {
                        ApiUtil.fwdApi.addDmzc(param);
                        DmzcjlQueryWindow dmzcjlQueryWindow = ServiceManager.getService(project, DmzcjlQueryWindow.class);
                        dmzcjlQueryWindow.queryZcjl();
                    }
                    Notification notification = NotificationUtil.create("走查记录添加成功！", "代码走查", NotificationType.INFORMATION);
                    notification.notify(project);
                    close(OK_EXIT_CODE);
                } catch (Exception e) {
                    MessageUtil.showErrorDialog(e.getMessage(), "添加失败");
                }
            }
        };
        return new Action[]{okAction};
    }
}
